/* 
 * File:   AnimationLogic.h
 * Author: RedEyedKiller
 *
 * Created on 21 Απρίλιος 2011, 12:58 μμ
 */

#ifndef ANIMATIONLOGIC_H
#define	ANIMATIONLOGIC_H


#include "AnimationFrame.h"
#include "DrawLogic.h"
#include "TimedUpdater.h"
#include <string>
#include <map>

class ScriptRegister;

namespace EntitySystem
{

class AnimationLogic : public DrawLogic
{
public:

    enum AfterEnd
    {
        /**
         * After the end of current animation the playback 
         * will stop. The last frame of the animation sequence will 
         * be displayed as a static image.
         */
        ANIM_ONESHOT,
        /**
         * After the end of current animation the same sequence will be played
         * again and again till further instruction.
         */
        ANIM_LOOPING,
        /**
         * After the end of current animation the animation will chang back to 
         * the default animation which will be ANIM_LOOPING.
         */
        ANIM_TODEFAULT
    };


    AnimationLogic();
    AnimationLogic(const AnimationLogic& orig);
    virtual ~AnimationLogic();
    virtual AnimationLogic* Clone();
    
    //In order this class stays compatible with the old Drawable hierarchy we needed
    //this virtual method.
    virtual void Draw(sdl::GraphicsCore *gCore, Camera *camera);

    /**
     * Request to play a specific animation. If animation doesn't exist default will be played instead
     * and an error will be logged under graphics channel.
     * @param animation - The animation to be played
     * @param afterEnd - Describes what will happen after the end of this animation.
     */
    void Play(const std::string& animation, AfterEnd afterEnd = ANIM_TODEFAULT);
    void Pause();
    void Resume();

    /**
     * Adds a new animation to the animationTable of this.
     * @param name - The key value of the animation. Also used by Play.
     * @param frame - The struct that describes this animation.
     */
    void AddFrame(const std::string& name, const AnimationFrame& frame);
    
    /**
     * Sets the frame into the requested frame.
     * If the frame doesn't exist false will be returned.
     * @param name
     * @param frame
     * @return 
     */
    bool GetFrame(const std::string& name,AnimationFrame& frame);
    
    void SetPlaying(bool playing);
    void SetCurrentFrame(int currentFrame);
    void SetCurrentAnimation(const std::string &currentAnimation);
    std::string GetCurrentAnimation() const;
    void SetDefaultAnimation(const std::string &defaultAnimation);

    /**
     * Overrides Draw Logic's GetWidth in order to supply valid image width.
     *
     * @return current frame's width.
     */

    virtual int GetWidth() const;


    /**
     * Overrides Draw Logic's GetHeight in order to supply valid image height.
     *
     * @return current frame's height.
     */

    virtual int GetHeight() const;


private:
    /**
     * Checks if currentFrame should proceed to next frame.
     * @param frame - The frame AnimationFrame of the currently playing animation.
     */
    void Update(AnimationFrame& frame,int* frameNumber);
    
    
    typedef std::map<std::string, AnimationFrame> AnimationTable;
    
    /**
     * The table with all animations of this AnimationLogic.
     */
    AnimationTable animationMap;

    /**
     * the default animation which will be played.
     */
    std::string defaultAnimation;

    /**
     * the animation which is currently active.
     */
    std::string currentAnimation;

    /**
     * used to keep in timing in animation.
     */
    TimedUpdater timer;

    /**
     * the current frame of the current animation sequence.
     * If a diffrent animation is set to current this value should be reset.
     */
    int currentFrame;

    /**
     * Describes what animation logic should do after the end of current animation.
     */
    AfterEnd afterEnd;

    /**
     * if false animation will stop to update and it will display a static image.
     */
    bool playing;

};

};
#endif	/* ANIMATIONLOGIC_H */

